package cn.com.infcn.monitor.task.jvm.impl;

import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryPoolMXBean;
import java.lang.management.MemoryUsage;
import java.util.Iterator;
import java.util.Set;

import javax.management.MBeanServerConnection;
import javax.management.ObjectName;

import org.apache.mina.core.session.IoSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cn.com.infcn.monitor.bean.IFCResponseBean;
import cn.com.infcn.monitor.jvm.bean.IFCJVMMemoryPool;
import cn.com.infcn.monitor.jvm.bean.IFCJVMMemoryUsage;
import cn.com.infcn.monitor.task.impl.BaseTask;
import cn.com.infcn.monitor.util.IFCBeanUtils;
import cn.com.infcn.monitor.util.IFCMinitorConstanst;

/**
 * 内存池的管理接口。
 * 内存池表示由 Java 虚拟机管理的内存资源，由一个或多个内存管理器对内存池进行管理。 
 * @author jijs
 *
 */
public class JVMMemoryPoolTask extends BaseTask {

	private final static Logger logger = LoggerFactory.getLogger(JVMMemoryPoolTask.class);

	public JVMMemoryPoolTask(IoSession session, Object message) {
		super(session, message);
	}

	@Override
	public void execute() throws Exception {
		IFCResponseBean result = jvmMemoryPool();
		sendResponse(result);
	}

	public IFCResponseBean jvmMemoryPool() {
		IFCResponseBean result = new IFCResponseBean();
		IFCJVMMemoryPool jvmMemoryPool = null;
		MemoryUsage usage = null;
		IFCJVMMemoryUsage ifcMemoryUsage = null;

		MBeanServerConnection mbs = null;
		try {
			// 获取MBeanServerConnection
			mbs = MBeanServerConnectionFactory.getInstance(IFCMinitorConstanst.JMXURL);
		} catch (IOException e) {
			logger.error("jmx.url 连接异常！" + e.getMessage());
			result.setResponseCode(IFCMinitorConstanst.MONITOR_RESPONSE_CODE_ERROR);
			result.setResponseMsg("jmx.url 连接异常！");
			return result;
		}

		try {

			ObjectName poolName = new ObjectName(ManagementFactory.MEMORY_POOL_MXBEAN_DOMAIN_TYPE + ",*");

			Set<ObjectName> mbeans = mbs.queryNames(poolName, null);
			if (mbeans != null) {

				jvmMemoryPool = new IFCJVMMemoryPool();

				Iterator<ObjectName> iterator = mbeans.iterator();
				while (iterator.hasNext()) {
					ObjectName objName = (ObjectName) iterator.next();
					System.out.println("objName:" + objName.getCanonicalName());
					MemoryPoolMXBean p = ManagementFactory.newPlatformMXBeanProxy(mbs, objName.getCanonicalName(),
							MemoryPoolMXBean.class);
					System.out.println("name:" + p.getName());

					usage = p.getCollectionUsage();
					if (usage == null) {
						continue;
					}
					ifcMemoryUsage = new IFCJVMMemoryUsage();
					IFCBeanUtils.copyProperties(usage, ifcMemoryUsage);

					if (objName.toString().indexOf("Eden Space") != -1) {
						jvmMemoryPool.setEdenMemoryUsage(ifcMemoryUsage);
					} else if (objName.toString().indexOf("Survivor Space") != -1) {
						jvmMemoryPool.setSurvivorMemoryUsage(ifcMemoryUsage);
					} else if (objName.toString().indexOf("Code Cache") != -1) {
						jvmMemoryPool.setCodeCacheMemoryUsage(ifcMemoryUsage);
					} else if (objName.toString().indexOf("Perm Gen") != -1) {
						jvmMemoryPool.setPermGenMemoryUsage(ifcMemoryUsage);
					} else if (objName.toString().indexOf("Old Gen") != -1) {
						jvmMemoryPool.setOldGenMemoryUsage(ifcMemoryUsage);
					} else if (objName.toString().indexOf("Metaspace") !=-1){
						jvmMemoryPool.setMetaspaceMemoryUsage(ifcMemoryUsage);
					}
				}
			}
			result.setResult(jvmMemoryPool);
			result.setResponseCode(IFCMinitorConstanst.MONITOR_RESPONSE_CODE_OK);
		} catch (Exception e) {
			logger.error(e.getMessage());
			result.setResponseCode(IFCMinitorConstanst.MONITOR_RESPONSE_CODE_ERROR);
			result.setResponseMsg(e.getMessage());
		}
		return result;
	}

	public static void main(String[] args) {
		JVMMemoryPoolTask task = new JVMMemoryPoolTask(null, null);
		IFCResponseBean result = task.jvmMemoryPool();
		IFCJVMMemoryPool jvmMemoryPool = (IFCJVMMemoryPool) result.getResult();

		IFCJVMMemoryUsage metaspaceMemoryUsage = jvmMemoryPool.getMetaspaceMemoryUsage();
		System.out.println(metaspaceMemoryUsage);
	}

}
